﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace PefStudio.SegyViewer
{
    public partial class TracePicture : UserControl
    {
        int _采样点数 = 0;
        int _道数 = 0;

        public int 采样点数
        {
            get
            {
                return _采样点数;
            }
            set
            {
                _采样点数 = value;
                vScrollBar.Maximum = value;
            }
        }

        public int 道数
        {
            get
            {
                return _道数;
            }
            set
            {
                _道数 = value;
                hScrollBar.Maximum = value;
            }
        }

        private bool _disablePaint = false;

        public FileInfo _FileInfo;
        public FileInfo FileInfo
        {
            get
            {
                return _FileInfo;
            }
            set
            {
                _FileInfo = value;

                _disablePaint = true;

                hScrollBar.Value = 0;
                vScrollBar.Value = 0;

                if (采样点数 <= 500)
                {
                    vScrollBar.Visible = false;
                }
                else
                    vScrollBar.Visible = true;

                if (道数 <= 100)
                {
                    hScrollBar.Visible = false;
                }
                else
                    hScrollBar.Visible = true;

                _disablePaint = false;

                TracePaint();
            }
        }

        public TracePicture()
        {
            InitializeComponent();

            hScrollBar.LargeChange = TracesPerPage;
            vScrollBar.LargeChange = SamplePointsPerPage;
        }

        int offsetWidth = 27;
        int offsetHeight = 15;

        private int _tracesPerPage = 100;
        public int TracesPerPage
        {
            get
            {
                return _tracesPerPage;
            }
            set
            {
                if (_tracesPerPage == value)
                    return;

                _tracesPerPage = value;
                hScrollBar.LargeChange = value;

                TracePaint();
            }
        }

        private int _samplePointsPerPage = 500;
        public int SamplePointsPerPage
        {
            get
            {
                return _samplePointsPerPage;
            }
            set
            {
                if (_samplePointsPerPage == value)
                    return;

                _samplePointsPerPage = value;
                vScrollBar.LargeChange = value;

                TracePaint();
            }
        }

        float _intervalWidth = 0.0F;
        float _intervalHeight = 0.0F;
 
        public void TracePaint()
        {
            if (FileInfo == null)
                return;

            if (_disablePaint == true)
                return;

            int visualWidth = pictureBox.ClientSize.Width - 2;
            int visualHeight = pictureBox.ClientSize.Height - 2;

            Bitmap bitmap = new Bitmap(visualWidth, visualHeight);
            Graphics g = Graphics.FromImage(bitmap);

            //横向100道、竖向500采样点
            _intervalWidth = Convert.ToSingle(visualWidth) / TracesPerPage;
            _intervalHeight = Convert.ToSingle(visualHeight) / SamplePointsPerPage;

            //横向虚线画笔
            Pen dashPen = new Pen(Color.Black);
            dashPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

            //竖向实线画笔
            Pen solidPen = new Pen(Color.Black);
            solidPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;

            Font font = new Font("宋体", 9);

            int start道数 = hScrollBar.Value;

            //竖线
            for (int 道 = start道数; 道 < start道数 + TracesPerPage; 道 += TracesPerPage / 5)
            {
                float x = offsetWidth + _intervalWidth * (道 - start道数);

                g.DrawLine(solidPen, x, 12, x, 15);

                if (道 == 0)
                    g.DrawString(道.ToString(), font, dashPen.Brush, x - 4, 0);
                else if (道 < 100)
                    g.DrawString(道.ToString(), font, dashPen.Brush, x - 7, 0);
                else if (道 < 1000)
                    g.DrawString(道.ToString(), font, dashPen.Brush, x - 10, 0);
                else if (道 < 10000)
                    g.DrawString(道.ToString(), font, dashPen.Brush, x - 13, 0);
            }

            int start采样点 = vScrollBar.Value;

            //横线
            for (int 点 = start采样点; 点 < start采样点 + SamplePointsPerPage; 点 += SamplePointsPerPage / 10)
            {
                float y = offsetHeight + _intervalHeight * (点 - start采样点);

                g.DrawLine(dashPen, offsetWidth + 0, y, visualWidth + offsetWidth + 0, y);

                g.DrawString(点.ToString("0"), font, dashPen.Brush, 0, y - 6);
            }

            BinaryReader br = new BinaryReader(FileInfo.OpenRead());

            br.BaseStream.Position = 3600 + (240 + 采样点数 * 4) * start道数;

            float 常数因子 = 1 / (60.0F * (TracesPerPage / 100));

            for (int 道 = 0; 道 < TracesPerPage; 道 += 1)
            {
                if (道 + start道数 >= 道数)
                    break;

                br.BaseStream.Position += 240;

                br.BaseStream.Position += start采样点 * 4;

                float[] pointValues = new float[SamplePointsPerPage];

                float baseValueOfTrace = offsetWidth + _intervalWidth * 道;

                
                for (int 点 = 0; 点 < SamplePointsPerPage; 点 += 1)
                {
                    if (点 + start采样点 >= 采样点数)
                    {
                        br.BaseStream.Position -= (点 + start采样点 - 采样点数 + 1) * 4;
                        break;
                    }
                    pointValues[点] = baseValueOfTrace + Utils.ReadIEEESingle(br.ReadBytes(4)) * 常数因子;
                }
                if (采样点数 - SamplePointsPerPage - start采样点 > 0)
                    br.BaseStream.Position += (采样点数 - SamplePointsPerPage - start采样点) * 4;

                PointF startPoint = new PointF(pointValues[0], offsetHeight);
                PointF endPoint;

                List<PointF> pointsPolygon = new List<PointF>();

                for (int 点 = 1; 点 < pointValues.Length - 1; 点++)
                {
                    if (pointValues[点 - 1] == baseValueOfTrace 
                        && pointValues[点] == baseValueOfTrace 
                        && pointValues[点 + 1] == baseValueOfTrace)
                    {
                        continue;
                    }

                    if (pointValues[点] > baseValueOfTrace)
                    {
                        if (pointValues[点 - 1] <= baseValueOfTrace)
                        {
                            pointsPolygon.Add(new PointF(baseValueOfTrace, _intervalHeight * (点 - 1) + offsetHeight));
                        }

                        pointsPolygon.Add(new PointF(pointValues[点], _intervalHeight * 点 + offsetHeight));

                        if (pointValues[点 + 1] <= baseValueOfTrace)
                        {
                            pointsPolygon.Add(new PointF(baseValueOfTrace, _intervalHeight * (点 + 1) + offsetHeight));
                            g.DrawPolygon(solidPen, pointsPolygon.ToArray());
                            g.FillPolygon(solidPen.Brush, pointsPolygon.ToArray());
                            pointsPolygon.Clear();
                        }

                        continue;
                    }

                    endPoint = new PointF(pointValues[点], _intervalHeight * 点 + offsetHeight);
                    
                    g.DrawLine(solidPen, startPoint, endPoint);
                    startPoint = endPoint;
                }

                endPoint = new PointF(pointValues[pointValues.Length - 1], _intervalHeight * (pointValues.Length - 1) + offsetHeight);
                g.DrawLine(solidPen, startPoint, endPoint);
            }

            pictureBox.Image = bitmap;
            vScrollBar.Refresh();
            hScrollBar.Refresh();
        }

        private void pictureBox_SizeChanged(object sender, EventArgs e)
        {
            TracePaint();
        }

        private void vScrollBar_ValueChanged(object sender, EventArgs e)
        {
            TracePaint();
        }

        private void hScrollBar_ValueChanged(object sender, EventArgs e)
        {
            TracePaint();
        }

        private void pictureBox_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("");
        }

        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (FileInfo == null)
            {
                lblStatus.Text = "";
                return;
            }

            int trace = Convert.ToInt32((e.X - offsetWidth) / _intervalWidth);
            int samplepoint = Convert.ToInt32((e.Y - offsetHeight) / _intervalHeight);

            if (trace >= 0 && samplepoint >= 0)
            {
                lblStatus.Text = "当前位置： " 
                    + (hScrollBar.Value + trace).ToString() + " 道   " 
                    + (vScrollBar.Value + samplepoint).ToString() + " 点";
            }
        }
    }
}
